﻿using Mozhi.Abp.Domain.BasicData.Repositories;
using Mozhi.Abp.Domain.BasicData;
using mozhi.smarterp.Business.Products.Repositories;
using mozhi.smarterp.Business.Products.Services;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;

namespace mozhi.smarterp.Business.Products
{
    public class ProductSaleSettingAppService : BusinessAppService , IProductSaleSettingAppService
    {
        private IProductSaleSettingRepository _repository;
        private ProductSaleSettingManager _manager;
        private IProductRepository _productRepository;
        private IUnitRepository _unitRepository;


        public ProductSaleSettingAppService(IProductSaleSettingRepository repository, ProductSaleSettingManager manager, IProductRepository productRepository,
            IUnitRepository unitRepository)
        {
            _repository = repository;
            _manager = manager;
            _productRepository = productRepository;
            _unitRepository = unitRepository;
        }

        public async Task<ProductSaleSettingDto> CreateAsync(ProductSaleSettingCreateDto input)
        {
            var saleSetting = await _manager.GetAsync(null, input.ProductId, input.SaleUnitId);

            saleSetting = await _repository.InsertAsync(saleSetting);

            var result = ObjectMapper.Map<ProductSaleSetting, ProductSaleSettingDto>(saleSetting);

            await LoadOtherInfoAsync(new List<ProductSaleSettingDto> { result });

            return result;
        }

        public async Task DeleteAsync(Guid productId)
        {
            var setting = await _repository.GetByProductIdAsync(productId);

            if (setting == null)
                return;

            await _repository.DeleteAsync(setting.Id);
        }

        public async Task<ProductSaleSettingDto> GetAsync(Guid productId)
        {
            var saleSetting = await _repository.GetByProductIdAsync(productId);

            var result = ObjectMapper.Map<ProductSaleSetting, ProductSaleSettingDto>(saleSetting);

            if (result == null)
                return result;

            await LoadOtherInfoAsync(new List<ProductSaleSettingDto> { result });

            return result;
        }

        public async Task<PagedResultDto<ProductSaleSettingDto>> GetListAsync(PagedAndSortedResultRequestDto filter)
        {
            var saleSettings = await _repository.GetPagedListAsync(filter.SkipCount, filter.MaxResultCount, filter.Sorting);

            var count = await _repository.GetCountAsync();

            var items = ObjectMapper.Map<List<ProductSaleSetting>, List<ProductSaleSettingDto>>(saleSettings);

            await LoadOtherInfoAsync(items);

            return new PagedResultDto<ProductSaleSettingDto>()
            {
                Items = items,
                TotalCount = count
            };
        }

        public async Task<ProductSaleSettingDto> UpdateAsync(ProductSaleSettingUpdateDto input)
        {
            var saleSetting = await _manager.GetAsync(input.Id, null, input.SaleUnitId);

            saleSetting = await _repository.UpdateAsync(saleSetting);

            var result = ObjectMapper.Map<ProductSaleSetting, ProductSaleSettingDto>(saleSetting);

            if (result == null)
                return result;

            await LoadOtherInfoAsync(new List<ProductSaleSettingDto> { result });

            return result;
        }

        #region
        private async Task LoadOtherInfoAsync(List<ProductSaleSettingDto> saleSettings)
        {
            if (saleSettings == null)
                return;

            foreach (var saleSetting in saleSettings)
            {
                var product = await _productRepository.GetAsync(saleSetting.ProductId);

                saleSetting.ProductCode = product?.Code;
                saleSetting.ProductName = product?.Name;

                var unit = await _unitRepository.GetAsync(saleSetting.SaleUnitId);

                saleSetting.SaleUnitName = unit?.Name;
            }
        }
        #endregion
    }
}
